package first.group.ssh.packet.writer;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;

public class NameListWriter {

    private static class NameListWriteState {

        private int length = 0;
        private final ByteBuffer buffer;
        private boolean first = true;

        public NameListWriteState(ByteBuffer buffer) {
            this.buffer = buffer;
            buffer.mark();
            // save space for length
            buffer.position(buffer.position() + 4);
        }
    }

    private static class ByteBufferSupplier implements Supplier<NameListWriteState> {

        private final NameListWriteState state;

        public ByteBufferSupplier(ByteBuffer buffer) {
            state = new NameListWriteState(buffer);
        }

        @Override
        public NameListWriteState get() {
            return state;
        }
    }

    private static class NameListAccumulator implements BiConsumer<NameListWriteState, String> {

        @Override
        public void accept(NameListWriteState state, String str) {
            byte[] data = str.getBytes(StandardCharsets.US_ASCII);
            if (state.first) {
                state.first = false;
            } else {
                state.buffer.put((byte) ',');
                state.length += 1;
            }
            state.buffer.put(data);
            state.length += data.length;
        }
    }

    public static class NameListCombiner implements BinaryOperator<NameListWriteState> {

        @Override
        public NameListWriteState apply(NameListWriteState t, NameListWriteState u) {
            throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
        }
    }

    private static class NameListFinisher implements Function<NameListWriteState, ByteBuffer> {

        @Override
        public ByteBuffer apply(NameListWriteState state) {
            state.buffer.reset();
            state.buffer.putInt(state.length);
            state.buffer.position(state.buffer.position() + state.length);
            return state.buffer;
        }
    }

    public static Collector<String, ?, ByteBuffer> of(ByteBuffer buffer) {
        return Collector.of(new ByteBufferSupplier(buffer), new NameListAccumulator(), new NameListCombiner(), new NameListFinisher());
    }
    
    public static void write(ByteBuffer buffer, List<String> strs) {
        strs.stream().collect(NameListWriter.of(buffer));
    }
}
